import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_soundmagus/extension/text_editing_controller.dart';
import 'package:flutter_soundmagus/widget/alert/alert.dart';
import 'package:flutter_soundmagus/widget/eq/eq.dart';
import 'package:get/get.dart';

final kPresetTitleDefault = 'Audio Presets';

class EqController extends GetxController with MsgParserRefreshMixin {
  ///频点索引0-30总共31个
  final pd = 0.obs;

  ///增益
  final db = 0.0.obs;

  ///q值
  final q = 0.05.obs;

  ///频率
  final freq = kFreqMin.obs;

  ///频点数
  final pdCount = 0.obs;

  ///当前选中通道
  final selectCH = 0.obs;

  ///频点页码
  final page = 0.obs;

  ///选中通道
  final selectCh = DataMng().eqModel.chConfig.selectCh.obs;

  ///底部导航选择状态
  final bottomSelects = List.generate(7, (index) => false.obs);

  ///预设选中索引
  final preset = kPresetTitleDefault.obs;

  ///通道选中状态
  final chSelects = List.generate(DataMng().eqModel.chConfig.chs.length, (index) => false.obs);

  TextEditingController textEditingControllerFreq = TextEditingController(text: '20');
  TextEditingController textEditingControllerDb = TextEditingController(text: '0');
  TextEditingController textEditingControllerQ = TextEditingController(text: '7.2');

  EQModel get eqModel => DataMng().eqModel;

  PageController pageController = PageController();

  EqController() {
    observeRefresh();

    // textEditingControllerFreq.addListener(freqChange);
    textEditingControllerDb.addListener(dbChange);
    // textEditingControllerQ.addListener(qChange);

    everAll([pd, selectCH], (v) {
      _refreshUI();
    });

    this.pdCount.value = 10;
    selectCH.value = 0;
    refreshData(false);
    _refreshUI();

    debounce(db, (v) => Msg.msgEq(), time: kMsgInterval);
    debounce(freq, (v) => Msg.msgEq(), time: kMsgInterval);
    debounce(q, (v) => Msg.msgEq(), time: kMsgInterval);
  }
  @override
  refreshData(bool needSendData) {
    super.refreshData(needSendData);
    // page.value = 0;

    //同步选中状态
    for (var i = 0; i < eqModel.chConfig.chs.length; i++) {
      chSelects[i].value = eqModel.chConfig.selecteds()[i];
    }

    //记忆上次选中的通道和频点
    selectCH.value = eqModel.chConfig.selectCh;
    updatePd(eqModel.pd);

    if (needSendData) {
      Msg.msgEqSendAllChsData();
    }
  }

  //刷新UI
  @override
  refreshState(bool needSendData) {
    super.refreshState(needSendData);
    _refreshUI();
    refresh();
  }

  _refreshUI() {
    textEditingControllerDb.zftext = eqModel.getCurrentItemModel().ch.toStringAsFixed(1);
    textEditingControllerFreq.zftext = eqModel.getCurrentItemModel().freq.toString();
    textEditingControllerQ.zftext = eqModel.getCurrentItemModel().q.toStringAsFixed(1);
  }

  void freqChange() {
    int freq = int.tryParse(textEditingControllerFreq.text) ?? 0;
    updateFreq(freq);
  }

  void dbChange() {
    var val = double.tryParse(textEditingControllerDb.text) ?? 0;
    updateDb(val);
  }

  void qChange() {
    var val = double.tryParse(textEditingControllerQ.text) ?? 0;
    updateQ(val);
  }

  ///选中频点
  void updatePd(int pd) {
    eqModel.pd = pd;
    this.pd.value = pd;
    q.value = eqModel.getCurrentItemModel().q;
    freq.value = eqModel.getCurrentItemModel().freq;
  }

  ///前一个频点
  void prevPd() {
    var pd = max(eqModel.pd - 1, 0);
    eqModel.pd = pd;
    this.pd.value = pd;
  }

  ///下一个频点
  void nextPd() {
    var pd = min(eqModel.pd + 1, eqModel.pdCount - 1);
    eqModel.pd = pd;
    this.pd.value = pd;
  }

  ///更新增益
  void updateDb(double db) {
    eqModel.updateEqItem(ch: db);
    textEditingControllerDb.zftext = db.toString();
    this.db.value = db;
  }

  void increaseDb() {
    var db = this.db.value;
    db++;
    db = min(db, 20);
    updateDb(db);
  }

  void decreaseDb() {
    var db = this.db.value;
    db--;
    db = max(db, -20);
    updateDb(db);
  }

  ///更新Q值
  void updateQ(double q) {
    q = kSafeQ(q);
    eqModel.updateEqItem(q: q);

    textEditingControllerQ.zftext = q.toStringAsFixed(2);
    this.q.value = q;
  }

  void editQ(bool isIncrease) {
    var v = q.value;
    if (isIncrease) {
      v += 0.05;
      v = min(v, kQMax);
    } else {
      v -= 0.05;
      v = max(v, kQMin);
    }
    updateQ(v);
  }

  ///更新频率
  void updateFreq(int v) {
    v = kSafeFreq(v);
    eqModel.updateEqItem(freq: v);

    textEditingControllerFreq.zftext = v.toString();
    this.freq.value = v;
  }

  void editFreq(bool isIncrease) {
    var v = freq.value;
    if (isIncrease) {
      v++;
      v = min(v, kFreqMax);
    } else {
      v--;
      v = max(v, kFreqMin);
    }
    updateFreq(v);
  }

  ///更新频点数
  void updatePdCount(int v) {
    eqModel
      ..pdCount = v
      ..pd = 0;
    this.pd.value = 0;
    this.pdCount.value = v;
  }

  ///更新选中频道
  void updateSelectCh(int ch) {
    eqModel.chConfig.selectCh = ch;
    selectCH.value = ch;

    for (var i = 0; i < eqModel.chConfig.chs.length; i++) {
      //同步选中状态
      chSelects[i].value = eqModel.chConfig.selecteds()[i];
    }
  }

  ///设置组联调[groupIndex]组索引
  void setGroup({required int groupIndex}) {
    Get.dialog(AlertSelectChannel(
      groupIndex: groupIndex,
      chConfig: eqModel.chConfig,
      onPressed: (i) {
        eqModel
          ..chConfig.setGroup(
            groupIndex: groupIndex,
            relativeCH: i,
          )
          ..syncData();
        selectCh.value = i;
        bottomSelects[groupIndex].value = true;

        for (var e in eqModel.chConfig.chs) {
          chSelects[e.index].value = e.groupIndex == groupIndex;
        }

        //下发一次数据
        final ch = eqModel.chConfig.getRelativeCh(ch: i);
        Msg.msgEqSendSingleChAllPdsData(ch);
      },
    ));
  }

  ///取消组联调
  void cancelGroup({required int groupIndex}) {
    eqModel.chConfig.cancelGroup(groupIndex: groupIndex);
    bottomSelects[groupIndex].value = false;

    var chs = eqModel.chConfig.chs.where((element) => element.groupIndex == groupIndex).toList();
    chSelects[chs.last.index].value = false; //组的第二个通道取消高亮
  }

  void onBottomNavPress(int i) {
    if (i < 4) {
      setGroup(groupIndex: i);
    } else if (i == 4) {
      //eq default
      bottomSelects[i].toggle();
    } else if (i == 5) {
      //audo preset
      // Get.dialog(AlertPreset(
      //   onPressed: (i, title) {
      //     preset.value = 'PRESET($title)';
      //     Preset.set(i);
      //     Future.delayed(Duration(milliseconds: 200),
      //         () => showLoading(duration: Duration(seconds: 5)));
      //   },
      // ));
    } else if (i == 6) {
      //reset eq
      //do nothing
    }
  }

  void onBottomNavLongPress(int i) {
    if (i < 4) {
      cancelGroup(groupIndex: i);
    } else if (i == 4) {
      //eq default
    } else if (i == 5) {
      //reset eq
      preset.value = kPresetTitleDefault;
      eqModel.reset();
      MsgParser.done(sendData: true);
    } else if (i == 6) {}
  }

  void prevPage() {
    pageController.previousPage(duration: Duration(milliseconds: 300), curve: Curves.easeIn);
  }

  void nextPage() {
    pageController.nextPage(duration: Duration(milliseconds: 300), curve: Curves.easeIn);
  }
}
